package io.github.liuqun.sandbox;

import io.minio.ListBucketsArgs;
import io.minio.ListObjectsArgs;
import io.minio.MinioClient;
import io.minio.Result;
import io.minio.messages.Bucket;
import io.minio.messages.Item;
import okhttp3.OkHttpClient;

import java.time.Duration;
import java.time.ZonedDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;

public class DemoAppBootstrap {

    public static void main(String[] args) throws Exception {
        System.out.println("Prepare and initialize a SDK client...");
        String accessKey = "foobar";
        String secretKey = "P@ssw0rd";
        String host = "192.168.1.12";
        short port = 9000;
        boolean useHttps = false;
        try (MinioClient _minioClient = prepareNewMinioClient(accessKey, secretKey, host, port, useHttps)) {
            System.out.println("List all buckets on Minio Server:");
            ListBucketsArgs listBucketsArgs = ListBucketsArgs.builder()
                    .build();
            List<Bucket> list = _minioClient.listBuckets(listBucketsArgs);

            if (list.isEmpty()) {
                System.err.println("main(): 无bucket或服务器连接失败...");
                return;
            }
            System.out.println("[");
            for (Bucket i : list) {
                System.out.println("  {");
                String bucketName = i.name();
                System.out.println("    bucketName: " + bucketName + ",");
                ZonedDateTime createdAt = i.creationDate();
                System.out.println("    createdAt: " + createdAt.toLocalDate());

                ListObjectsArgs listObjectsArgs = ListObjectsArgs.builder()
                        .bucket(bucketName)
                        .build();
                Iterable<Result<Item>> results = _minioClient.listObjects(listObjectsArgs);
                System.out.println("    objectList: [");
                for (Result<Item> j : results) {
                    Item item = j.get();
                    System.out.println("      {");
                    String objectName = item.objectName();
                    if (item.isDir()) {
                        System.out.println("        directory: '" + objectName + "',");
                    }
                    if (!item.isDir()) {
                        System.out.println("        objectName: '" + objectName + "',");
                        String etag = item.etag();
                        if (null != etag) {
                            System.out.println("        etag: '" + etag + "',");
                        }
                        long size = item.size();
                        System.out.println("        size: '" + size + " bytes',");
                        ZonedDateTime lastModified;
                        if (null != (lastModified = item.lastModified())) {
                            System.out.println("        lastModified: '" + lastModified.toLocalDate() + "',");
                        }
                    }
                    System.out.println("      },");
                }
                System.out.println("    ],");
                System.out.println("  },");
            }
            System.out.println("]");

        } catch (Exception err) {
            System.err.println("Error: " + err.getMessage() + " ErrorType= "+err.getClass().getSimpleName());
        }
    }

    /**
     * @param accessKey 用户名
     * @param secretKey 登录密码
     * @param host      主机名或IP地址字符串
     * @param port      端口号
     * @param useHttps  true启用https; false不启用https
     * @return 创建 Java SDK 客户端实例
     */
    private static MinioClient prepareNewMinioClient(
            String accessKey,
            String secretKey,
            String host,
            int port,
            boolean useHttps) {
        // 手动加长TCP握手和收发数据的等待超时时长,
        // 目的: 为了在单步调试客户端时避免等待时间太长而触发okHttp默认的30秒超时限制
        Duration maxConnectTimeout = Duration.of(999, ChronoUnit.SECONDS);
        Duration maxReadTimeout = Duration.of(999, ChronoUnit.SECONDS);
        Duration maxWriteTimeout = Duration.of(999, ChronoUnit.SECONDS);
        OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder()
                .connectTimeout(maxConnectTimeout)
                .readTimeout(maxReadTimeout)
                .writeTimeout(maxWriteTimeout);
        OkHttpClient okHttpClient = okHttpClientBuilder.build();

        // MinIO 客户端初始化
        MinioClient.Builder builder = MinioClient.builder();
        builder.httpClient(okHttpClient);
        builder.credentials(accessKey, secretKey);
        builder.endpoint(host, port, useHttps);
        return builder.build();
    }
}
